动态表单 + 表单校验功能
概述
由于表单使用响应式对象定义 schema 结构,因此天然具备动态能力。本节验证动态添加 schema 的响应式更新,并实现表单校验功能。
动态 Schema 演示
动态添加表单项
// 动态新增 schema
const newSchema = [
{ field: 'name1', type: 'input', value: '', label: '动态字段1' },
{ field: 'name2', type: 'input', value: '', label: '动态字段2' },
{ field: 'name3', type: 'input', value: '', label: '动态字段3' },
]
function addSchema() {
// 将新 schema 追加到已有 schema 中
schema.push(...newSchema)
}
typescript
响应式原理
schema (reactive)
│
│ push(newItems)
▼
schema 自动更新
│
▼
useForm 内部 setForm 自动触发
│
▼
model 新增 name1, name2, name3 字段
│
▼
VFormLayout 重新渲染 → 新增 3 个输入框
text
常见疑问解答
| 疑问 | 回答 |
|---|---|
| push 后 model 会自动更新吗? | 会。schema 是 reactive 对象,push 触发响应式更新 |
需要用 watch 监听吗? | 不需要。reactive 本身就是响应式的 |
需要用 computed 吗? | 不需要。直接操作 reactive 数组即可 |
表单校验
校验规则定义
const schema = reactive([
{
field: 'username',
type: 'input',
value: '',
label: '用户名',
rules: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' },
],
},
{
field: 'email',
type: 'input',
value: '',
label: '邮箱',
rules: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' },
],
},
])
typescript
校验方法实现
import type { FormItemProp } from 'element-plus'
async function validate(props: FormItemProp[]): Promise<boolean> {
try {
await formRef.value?.validate(props)
return true
} catch {
return false
}
}
typescript
Layout 改造:使用 ElSpace
替换 VFormLayout
将 v-form-layout 替换为 v-form-layout-wrapper,使用 ElSpace 作为基础结构:
<template>
<el-space direction="vertical" :size="16" fill class="w-full">
<VFormItem
v-for="item in schema"
:key="item.field"
v-model:model-value="model[item.field]"
:item="item"
/>
</el-space>
</template>
vue
| 改造项 | 改造前 | 改造后 |
|---|---|---|
| 布局容器 | 自定义 Flex 布局 | ElSpace 统一间距 |
| 间距控制 | 手动 margin | :size="16" 统一配置 |
| 宽度填充 | 需手动设置 | fill 自动填满 |
关键要点
reactive对象的push操作自动触发响应式更新,无需watch或computed- 动态添加 schema 后,model 和 formValue 同步更新,UI 自动渲染新表单项
- 表单校验规则通过
rules字段配置,类型来自 Element Plus 的FormItemProp ElSpace作为表单布局容器,统一管理表单项间距
↑